<?php

namespace App\Models;


use App\Service\Base\Model;
use Illuminate\Support\Facades\DB;

class Order extends Model
{

    // 用户管理
    protected $table = 'order';

    // 缓存字段，用于搜索绑定的字段
    protected $cacheFields = ['id', 'uid', 'event_id'];


    // {"id":"自编号","uid":"用户ID","event_id":"活动ID","order_no":"订单编号","number":"报名人数","paytime":"支付时间","status":"状态（0-未支付，1-已经支付，已经结束：根据活动来）","is_refund":"退款（0-否，1-申请，2-审核通过，3-审核失败，4-退款完成）","ctime":"下单时间","mtime":"更新时间"}

    // 订单支付 => 支付模型：进行支付操作

    // 支付类型
    public function getRefundStatus($getKey = true)
    {
        $channels = ['4' => '完成', '3' => '审核失败', '2' => '审核通过', '1' => '已经申请', '0' => '未申请',];
        if(empty($getKey)){
            return $channels;
        }

        return array_keys($channels);
    }

    // 审核状态
    public function getVerify($getKey = true)
    {
        $channels = ['2' => '审核失败', '1' => '审核通过', '0' => '未审核',];
        if(empty($getKey)){
            return $channels;
        }

        return array_keys($channels);
    }


    // 下订单：可能多个用户
    //  $users 字段 uid,event_id,order_uid,username,mobile
    public function makeOrder($uid, $event_id, $users, $share_uid = 0, $payMoney = 0)
    {
        // 查询活动信息
        $eventInfo = (new Event())->isCache(true)->oneFind(['id' => $event_id]);
        if(empty($eventInfo)){
            return $this->return_false('该活动不存在或者已经被删除！');
        }
        if($eventInfo['verify'] != 1){
            return $this->return_false('该活动未通过审核，不能报名！');
        }
        if($eventInfo['is_sale'] != 1){
            return $this->return_false('该活动已经下架，不能报名！');
        }
        if(($eventInfo['organ_price'] < 0) || ($eventInfo['person_price'] < 0)){
            return $this->return_false('该活动金额设置小于0，不能下单！');
        }

        // 查询用户信息
        $userInfo = (new User())->isCache(true)->oneFind(['id' => $uid]);
        if(empty($userInfo)){
            return $this->return_false('该操作用户不存在！');
        }

        // 查询 配置信息
        $config = (new SiteConfig())->getConfig();
        $config = array_column($config, 'value', 'field');

        // 配置信息验证


        // 没有认证的用户 只能为自己报名
        // 认证的用户 最多只能为10个人报名
        $allUsers  = $this->checkOrderUser($userInfo, $users);
        $agent_uid = $userInfo['agent_uid'];
        if($allUsers === false){
            return false;
        }
        if(empty($allUsers)){
            return $this->return_false('请指定正确的报名用户！');
        }

        // 计算代理 平台金额
        $number        = count($allUsers);
        $organ_amount  = $eventInfo['organ_price'] * $number;
        $person_amount = $eventInfo['person_price'] * $number;
        $platform_rate = max($config['platform_rate'] ?? 15, 0) / 100;    // 平台收入比例（该比例不能小于0）
        $agent_rate    = max($config['agent_rate'] ?? 0, 0) / 100;        // 代理商收入比例（该比例不能小于0）
        $pay_money     = $userInfo['verify'] == 1 ? $organ_amount : $person_amount;
        $pay_money     = $person_amount;  // 为了平衡展示所有收支，支付金额都是按个人价格进行支付的，机构报名返回差额
        $uid_money     = $userInfo['verify'] == 1 ? $person_amount - $organ_amount : 0;;  // 为了平衡展示所有收支，支付金额都是按个人价格进行支付的，机构报名返回差额    // 机构报名返回的金额
        $agent_money    = 0;
        $share_money    = 0;
        $platform_money = $person_amount * $platform_rate;  // 平台金额
        if($agent_uid){
            $agent_money    = $person_amount * $agent_rate;
            $platform_money = $platform_money - $agent_money;
        }
        if($share_uid){
            $share_money = $pay_money - $organ_amount - $uid_money;  // 机构报名，分享佣金为0
        }
        // 发布者金额
        $publish_money = $pay_money - $platform_money - $share_money - $uid_money;
        if($payMoney && ($payMoney !== $person_amount)){
            return $this->return_false('支付金额错误！');
        }


        // 各种金额的计算
        $money = [
            'order_id'       => 'required',
            'number'         => $number,
            'organ_price'    => $eventInfo['organ_price'],    // 单价：用于计算
            'person_price'   => $eventInfo['person_price'],   // 单价：用于计算
            'organ_amount'   => $organ_amount,                // 总价：用于计算
            'person_amount'  => $person_amount,               // 总价：用于计算
            'platform_rate'  => $platform_rate,               // 平台扣款比例
            'agent_rate'     => $agent_rate,                  // 代理商比例
            'pay_money'      => $pay_money,  // 为了平衡展示所有收支，支付金额都是按个人价格进行支付的
            'platform_money' => $platform_money,

            'uid'         => $uid,
            'agent_uid'   => $agent_uid,
            'share_uid'   => $share_uid,
            'publish_uid' => $eventInfo['uid'],

            'uid_money'     => max($uid_money, 0),     // 机构报名返回的金额，如果是个人报名则不会返回
            'agent_money'   => max($agent_money, 0),   // 金额必须 >0
            'share_money'   => max($share_money, 0),   // 金额必须 >0
            'publish_money' => max($publish_money, 0), // 金额必须 >0
        ];

        // 订单数据
        $_no      = $this->makeOrderNo($uid);  // 订单号
        $_last    = $eventInfo['dead_time'] - 1800;  // 最后支付时间 是报名结束前半个小时
        $_last    = $eventInfo['dead_time'];  // 最后支付时间 是报名结束时间（提前半个小时不能退款）
        $orderArr = ['uid' => $uid, 'event_id' => $event_id, 'order_no' => $_no, 'money' => $person_amount, 'number' => $number, 'last_paytime' => $_last, 'status' => 0,];
        $this->fill($orderArr);

        // 保存数据
        $ouDb = new OrderUser();
        $omDb = new OrderMoney();
        DB::beginTransaction();
        try{

            // 添加订单
            $this->save();
            $orderId = $this->id;

            // 增加订单金额
            $money['order_id'] = $orderId;
            $omDb->fill($money);
            $result = $omDb->save();

            // 添加：订单用户
            foreach($allUsers as $item){
                $item['uid']      = $uid;
                $item['order_id'] = $orderId;
                $item['event_id'] = $event_id;

                // 保存
                $result = $ouDb->insert($item);
            }

            // 添加支付记录


            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }

        // 整理字段信息
        $orderArr['id'] = $orderId;
        // 删除缓存
        $this->deleteCacheShow($orderArr);

        return $orderArr;
    }

    // 退订单
    public function refundOrder($uid, $order_id, $user_ids)
    {
        $orderDb  = new Order();
        $oUserDb  = new OrderUser();
        $oMoneyDb = new OrderMoney();

        // 查询订单
        $orderInfo = $orderDb->isCache(true)->oneFind(['id' => $order_id]);
        if(empty($orderInfo)){
            return $this->return_false('你选择的退款订单不存在或者已经被删除！');
        }
        if(empty($orderInfo['paytime']) || ($orderInfo['status'] != 1)){
            return $this->return_false('订单未支付，不能在退款！');
        }
        if(LARAVEL_TIME - $orderInfo['paytime'] > 86400 * 365){
            return $this->return_false('订单操作一年，不能在退款！');
        }
        if($uid != $orderInfo['uid']){
            return $this->return_false('这个订单不是你的，你不能退款！');
        }
        if(!in_array($orderInfo['is_refund'], [0, 4])){
            return $this->return_false('这个订单还在退款中，暂时不能在退款！');
        }

        // 查询订单用户
        $allUsers   = [];  // 构建新的订单用户
        $orderUsers = $oUserDb->whereIn('id', $user_ids)->where('order_id', $order_id)->get()->toArray();
        if(count($orderUsers) != count($user_ids)){
            return $this->return_false('你选择的订单用户不存在该订单中！');
        }
        foreach($orderUsers as $item){
            if($item['is_refund'] == 1){
                if($item['status_refund'] == 1){
                    return $this->return_false('你选择的订单用户已经退款，不能退款！');
                }
                if($item['status_refund'] == 0){
                    return $this->return_false('你选择的订单用户已经退款中，现在不能退款！');
                }
            }

            // 构建新的订单用户
            $allUsers[] = [
                'student_id'  => $item['student_id'],
                'order_uid'   => $item['order_uid'],
                'person_name' => $item['person_name'],
                'head_img'    => $item['head_img'],
                'sex'         => $item['sex'],
                'age'         => $item['age'],
                'guardor'     => $item['guardor'],
                'mobile'      => $item['mobile'],
                'old_id'      => $item['id'],
            ];
        }

        // 下单用户信息
        $userInfo = (new User())->isCache(true)->oneFind(['id' => $uid]);
        if(empty($userInfo)){
            return $this->return_false('该操作用户不存在！');
        }

        // 获取订单收益用户
        $moneyInfo = $oMoneyDb->isCache(true)->oneFind(['order_id' => $order_id]);
        $number    = count($user_ids);
        $event_id  = $orderInfo['event_id'];
        if(empty($moneyInfo)){
            //return $this->return_false('你选择的退款订单资金不存在！');

            // 如果没有订单金额 则重新计算
            // 查询活动信息
            $eventInfo = (new Event())->isCache(true)->oneFind(['id' => $event_id]);
            if(empty($eventInfo)){
                return $this->return_false('该活动不存在或者已经被删除！');
            }
            if(($eventInfo['organ_price'] < 0) || ($eventInfo['person_price'] < 0)){
                return $this->return_false('该活动金额设置小于0，不能下单！');
            }

            // 查询 配置信息
            $config    = (new SiteConfig())->getConfig();
            $config    = array_column($config, 'value', 'field');
            $moneyInfo = [
                'uid'           => $uid,
                'agent_uid'     => $userInfo['agent_uid'],
                'publish_uid'   => $eventInfo['uid'],
                'share_uid'     => 0,
                'organ_price'   => $eventInfo['organ_price'],
                'person_price'  => $eventInfo['person_price'],
                'platform_rate' => max($config['platform_rate'] ?? 15, 0) / 100,   // 平台收入比例（该比例不能小于0）
                'agent_rate'    => max($config['agent_rate'] ?? 0, 0) / 100,       // 代理商收入比例（该比例不能小于0）
            ];
        }


        // 各种价格计算
        $_uid          = $moneyInfo['uid'];
        $publish_uid   = $moneyInfo['publish_uid'];
        $agent_uid     = $moneyInfo['agent_uid'];
        $share_uid     = $moneyInfo['share_uid'];
        $organ_price   = $moneyInfo['organ_price'];
        $person_price  = $moneyInfo['person_price'];
        $platform_rate = $moneyInfo['platform_rate'];      // 平台收入比例
        $agent_rate    = $moneyInfo['agent_rate'];         // 代理商收入比例
        $organ_amount  = $organ_price * $number;
        $person_amount = $person_price * $number;

        // 为了平衡展示所有收支，支付金额都是按个人价格进行支付的，机构报名返回差额    // 机构报名返回的金额
        $uid_money = $userInfo['verify'] == 1 ? $person_amount - $organ_amount : 0;
        // 重新配置收益订单用户
        $pay_money      = $person_amount;  // 为了平衡展示所有收支，支付金额都是按个人价格进行支付的，机构报名返回差额
        $agent_money    = 0;
        $share_money    = 0;
        $platform_money = $person_amount * $platform_rate;  // 平台金额
        if($agent_uid){
            $agent_money    = $person_amount * $agent_rate;
            $platform_money = $platform_money - $agent_money;
        }
        if($share_uid){
            $share_money = $pay_money - $organ_amount - $uid_money;  // 机构报名，分享佣金为0
        }
        // 发布者金额
        $publish_money = $pay_money - $platform_money - $share_money - $uid_money;


        // 各种金额的计算
        $money = [
            'order_id'       => 'required',
            'number'         => $number,
            'organ_price'    => $organ_price,    // 单价：用于计算
            'person_price'   => $person_price,   // 单价：用于计算
            'organ_amount'   => $organ_amount,                // 总价：用于计算
            'person_amount'  => $person_amount,               // 总价：用于计算
            'platform_rate'  => $platform_rate,               // 平台扣款比例
            'agent_rate'     => $agent_rate,                  // 代理商比例
            'pay_money'      => $pay_money,  // 为了平衡展示所有收支，支付金额都是按个人价格进行支付的
            'platform_money' => $platform_money,

            'uid'         => $uid,
            'agent_uid'   => $agent_uid,
            'share_uid'   => $share_uid,
            'publish_uid' => $publish_uid,

            'uid_money'     => (-1) * max($uid_money, 0),   // 机构报名返回的金额，如果是个人报名则不会返回
            'agent_money'   => (-1) * max($agent_money, 0),
            'share_money'   => (-1) * max($share_money, 0),
            'publish_money' => (-1) * max($publish_money, 0),
        ];

        // 订单数据
        $_no      = $this->makeOrderNo($uid);  // 订单号
        $orderArr = ['uid' => $uid, 'event_id' => $event_id, 'order_no' => $_no, 'money' => $person_amount, 'number' => $number, 'last_paytime' => 0, 'status' => 0, 'old_id' => $orderInfo['id'], 'old_no' => $orderInfo['order_no'],];
        $this->fill($orderArr);

        // 保存数据
        DB::beginTransaction();
        try{

            // 添加订单
            $this->save();
            $orderId = $this->id;

            // 增加订单金额
            $money['order_id'] = $orderId;
            $oMoneyDb->fill($money);
            $result = $oMoneyDb->save();

            // 添加：订单用户
            foreach($allUsers as $item){
                $item['uid']      = $uid;
                $item['order_id'] = $orderId;
                $item['event_id'] = $event_id;

                // 保存
                $result = $oUserDb->insert($item);
            }

            // 原来的订单处理：退款中
            $this->where('id', $order_id)->update(['is_refund' => 1]);

            // 原来的订单用户：退款中
            $oUserDb->whereIn('id', $user_ids)->update(['is_refund' => 1]);

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }

        // 整理字段信息
        $orderArr['id']     = $orderId;
        $orderArr['old_no'] = $orderInfo['order_no'];

        // 删除缓存
        $this->deleteCacheShow($orderArr);

        return $orderArr;
    }

    // 生成订单编号
    public function makeOrderNo($uid)
    {
        $orderNo = $uid.'_'.date("YmdHis").'_'.random(4);

        return $orderNo;
    }

    // 生成订单编号
    public function makeOrderNo2()
    {
        $orderNo = date("YmdHis").'_'.random(4);
        $info    = $this->where('order_no', $orderNo)->first();
        if(empty($info)){
            return $orderNo;
        }

        return $this->makeOrderNo2();
    }

    // 检查报名用户信息
    // 没有认证的用户 只能为自己报名
    // 认证的用户 最多只能为10个人报名
    protected function checkOrderUser($myUser, $users)
    {
        // 判断是否认证
        //    认证用户可以下单10人，否则只能报名一人
        $is_auth = false;
        if($myUser['is_auth'] && ($myUser['verify'] == 1)){
            $is_auth = true;
        }

        $number = count($users);
        if(empty($number)){
            return $this->return_false('请指定报名用户！');
        }
        if(empty($is_auth)){
            if(empty($users['person_name']) || empty($users['age']) || empty($users['sex']) || empty($users['mobile']) || empty($users['guardor'])){
                return $this->return_false('传递的用户数据确实必要信息！');
            }

            $news = [
                'student_id'  => 0,
                'order_uid'   => $myUser['id'],
                'person_name' => $users['person_name'],
                'head_img'    => $this->randHeadImg($myUser['head_img']),
                'sex'         => $users['sex'],
                'age'         => $users['age'],
                'guardor'     => $users['guardor'],
                'mobile'      => $users['mobile'],
            ];

            // 重新组合
            $allUsers = [$news];
        } else{
            if($number > 10){
                return $this->return_false('你最多一次性只能为10个人报名！');
            }

            // 学员id
            $sIds = array_column($users, 'student_id');
            $sIds = $sIds ?: $users;
            // 查询学员信息
            $stds = (new Student())->isCache(true)->getListInIds($sIds);
            // 整理 报名学员信息
            $allUsers = [];
            $isNotStu = false;
            foreach($stds as $_stu){
                // 判断学员是不是这个组织的
                if($_stu['uid'] !== $myUser['id']){
                    // 不能在 foreach 内部直接 return 否则报错
                    //return $this->return_false('该学员学员不是你的学员！');
                    $isNotStu = true;
                    break;
                }

                // 组合数据
                $allUsers[] = [
                    'student_id'  => $_stu['id'],
                    'order_uid'   => $_stu['uid'],
                    'person_name' => $_stu['person_name'],
                    'head_img'    => $this->randHeadImg($_stu['head_img']),
                    'sex'         => $_stu['sex'],
                    'age'         => $_stu['age'],
                    'guardor'     => $_stu['guardor'],
                    'mobile'      => $_stu['mobile'],
                ];
            }
            if($isNotStu){
                return $this->return_false('该学员学员不是你的学员！');
            }
        }

        return $allUsers;
    }

    // 随机用户头像
    public function randHeadImg($url = '')
    {
        if($url){
            return $url;
        }

        // 从数组中随机获取
        // $imgs = [];
        // $_key = array_rand($imgs);
        // $img  = $imgs[$_key];

        // 从七牛云中获取
        // 纯色头像：已经删除 'https://img.shenlanhui.com/static/sys_head_img/face_'.rand(1, 75).'.jpg';
        // 一般头像 'https://img.shenlanhui.com/static/head_img/face_'.rand(1, 450).'.jpg';
        $img = 'https://img.shenlanhui.com/static/head_img/face_'.rand(1, 450).'.jpg';

        return $img;
    }

    // 定义验证操作
    public function rules()
    {

        $add = [
        ];

        $edit = [
        ];

        $info = [
        ];


        $rule = [
            'uid'       => 'required',
            'event_id'  => 'required',
            'order_no'  => 'required',
            'number'    => 'required',
            //'paytime'   => 'required',
            'status'    => 'in:0,1',
            'is_refund' => 'in:0,1,2,3,4',
        ];


        $msg = [
            'id'        => '自编号',
            'uid'       => '用户ID',
            'event_id'  => '活动ID',
            'order_no'  => '订单编号',
            'number'    => '报名人数',
            'paytime'   => '支付时间',
            'status'    => '状态（0-未支付，1-已经支付，已经结束：根据活动来）',
            'is_refund' => '退款（0-否，1-申请，2-审核通过，3-审核失败，4-退款完成）',
            'ctime'     => '下单时间',
            'mtime'     => '更新时间',
        ];

        return ['rule' => $rule, 'msg' => $msg, 'add' => $add];
    }

}
